<?php
class Array {
	
	public static function coalesce($array) {
		$args = func_get_args();
		while (TRUE) {
			$key = next($args);
			if ($key) {
				$value = self::get($array, $key);
				if ($value) {
					return $value;
				}
			} else {
				return NULL;
			}
		}
	}
	
	/**
	 * Get an item from an array using "dot" notation.
	 *
	 * @param  array   $array
	 * @param  string  $key
	 * @param  mixed   $default
	 * @return mixed
	 */
	public static function get_have($array, $key, $default = null) {
		if (isset($array[$key]) && ! empty($array[$key])) {
			return $array[$key];
		} elseif (strpos($key, '.')) {
			foreach (explode('.', $key) as $segment) {
				if ( ! is_array($array) || ! array_key_exists($segment, $array) || empty($array[$segment])) {
					return $default;
				} else {
					$array = $array[$segment];
				}
			}
			return $array;
		} else {
			return $default;
		}
	}

	/**
	 * Get an item from an array using "dot" notation.
	 *
	 * @param  array   $array
	 * @param  string  $key
	 * @param  mixed   $default
	 * @return mixed
	 */
	public static function get($array, $key, $default = null) {
		if (isset($array[$key])) {
			return $array[$key];
		} elseif (strpos($key, '.')) {
			foreach (explode('.', $key) as $segment) {
				if ( ! is_array($array) || ! array_key_exists($segment, $array)) {
					return $default;
				} else {
					$array = $array[$segment];
				}
			}
			return $array;
		} else {
			return $default;
		}
	}

	/**
	 * Check if an item exists in an array using "dot" notation.
	 *
	 * @param  array   $array
	 * @param  string  $key
	 * @return bool
	 */
	public static function has($array, $key) {
		if (empty($array) || ! is_scalar($key)) {
			return false;
		}

		if (array_key_exists($key, $array)) {
			return true;
		}

		foreach (explode('.', $key) as $segment) {
			if ( ! is_array($array) || ! array_key_exists($segment, $array)) {
				return false;
			}

			$array = $array[$segment];
		}

		return true;
	}

}
